package com.Demo1;

import java.util.concurrent.PriorityBlockingQueue;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: fzykd
 * Date: 2022-12-04
 * Time: 16:18
 */
//创建一个类 表示定时器中的 一个任务
class MyTask implements Comparable<MyTask>{
    //具体任务
    private Runnable runnable;
    //任务什么时候执行
    private long time;

    //构造方法 构造任务
    public MyTask(Runnable runnable,long after){
        this.runnable = runnable;
        this.time = System.currentTimeMillis() + after;
    }

    public long getTime(){
        return time;
    }

    public void run(){
        runnable.run();
    }

    //比较时间的方法
    public int compareTo(MyTask o){
        return (int) (this.time - o.time);
    }
}

//创建一个类 表示的是 定时器
//定时器中 组织 和 布置 创建的任务
class MyTimer {
    //定时器中存放多个任务 线程安全的阻塞队列 内部是一个堆实现的 堆的排序要明确 按照时间大小来排序
    private PriorityBlockingQueue<MyTask> queue = new PriorityBlockingQueue<>();

    //定时器中布置任务的方法
    public void schedule(Runnable runnable,long delay){
        MyTask task = new MyTask(runnable,delay);
        queue.put(task);
        //有新的任务进来 去通知他 重新检查任务时间
        synchronized (locker){
            locker.notify();
        }
    }

    private Object locker = new Object();

    //构造方法 构造timer 有一个单独的线程 不断的检查是否又时间到了的线程 然后执行
    public MyTimer(){
        Thread t = new Thread(()->{
            while (true){
                //先取出队首元素
                try {
                    MyTask task = queue.take();
                    long curTime = System.currentTimeMillis();
                    if (curTime < task.getTime()){
                        //时间没到 任务放回到队列中
                        queue.put(task);

                        synchronized (locker){
                            //避免忙等 设置一个等待时间
                            locker.wait(task.getTime() - curTime);
                        }
                    }else {
                        //时间到了 执行任务
                        task.run();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
}

//实现一个自己版本的定时器
public class Demo3 {
    public static void main(String[] args) {
        MyTimer myTimer = new MyTimer();
        myTimer.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("定时器");
            }
        },3000);

        System.out.println("main");
    }
}
